package main

import (
	"context"
	"encoding/json"
	"fmt"
	"strings"

	"github.com/mark3labs/mcp-go/mcp"
)

// parseArguments 解析请求参数的辅助函数
func parseArguments(arguments any, target interface{}) error {
	argsBytes, ok := arguments.([]byte)
	if !ok {
		var err error
		argsBytes, err = json.Marshal(arguments)
		if err != nil {
			return fmt.Errorf("failed to marshal arguments: %v", err)
		}
	}
	return json.Unmarshal(argsBytes, target)
}

// 集群信息处理函数
func (k *K8sMCPServer) handleGetClusterInfo(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	output, err := k.executeKubectl("cluster-info")
	if err != nil {
		return mcp.NewToolResultError(fmt.Sprintf("获取集群信息失败: %v", err)), nil
	}

	return mcp.NewToolResultText(string(output)), nil
}

// 获取节点信息
func (k *K8sMCPServer) handleGetNodes(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	args := request.GetArguments()
	outputFormat := "wide"

	if format, ok := args["output_format"]; ok && format != nil {
		if formatStr, ok := format.(string); ok {
			outputFormat = formatStr
		}
	}

	output, err := k.executeKubectl("get", "nodes", "-o", outputFormat)
	if err != nil {
		return mcp.NewToolResultError(fmt.Sprintf("获取节点信息失败: %v", err)), nil
	}

	return mcp.NewToolResultText(string(output)), nil
}

// 获取Pod信息
func (k *K8sMCPServer) handleGetPods(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	args := request.GetArguments()
	namespace := k.config.Namespace
	outputFormat := "wide"
	selector := ""

	if ns, ok := args["namespace"]; ok && ns != nil {
		if nsStr, ok := ns.(string); ok && nsStr != "" {
			namespace = nsStr
		}
	}

	if format, ok := args["output_format"]; ok && format != nil {
		if formatStr, ok := format.(string); ok {
			outputFormat = formatStr
		}
	}

	if sel, ok := args["selector"]; ok && sel != nil {
		if selStr, ok := sel.(string); ok && selStr != "" {
			selector = selStr
		}
	}

	kubectlArgs := []string{"get", "pods", "-n", namespace, "-o", outputFormat}
	if selector != "" {
		kubectlArgs = append(kubectlArgs, "-l", selector)
	}

	output, err := k.executeKubectl(kubectlArgs...)
	if err != nil {
		return mcp.NewToolResultError(fmt.Sprintf("获取Pod信息失败: %v", err)), nil
	}

	return mcp.NewToolResultText(string(output)), nil
}

// 获取Deployment信息
func (k *K8sMCPServer) handleGetDeployments(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	args := request.GetArguments()
	namespace := k.config.Namespace
	outputFormat := "wide"

	if ns, ok := args["namespace"]; ok && ns != nil {
		if nsStr, ok := ns.(string); ok && nsStr != "" {
			namespace = nsStr
		}
	}

	if format, ok := args["output_format"]; ok && format != nil {
		if formatStr, ok := format.(string); ok {
			outputFormat = formatStr
		}
	}

	output, err := k.executeKubectl("get", "deployments", "-n", namespace, "-o", outputFormat)
	if err != nil {
		return mcp.NewToolResultError(fmt.Sprintf("获取Deployment信息失败: %v", err)), nil
	}

	return mcp.NewToolResultText(string(output)), nil
}

// 获取Service信息
func (k *K8sMCPServer) handleGetServices(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	args := request.GetArguments()
	namespace := k.config.Namespace
	outputFormat := "wide"

	if ns, ok := args["namespace"]; ok && ns != nil {
		if nsStr, ok := ns.(string); ok && nsStr != "" {
			namespace = nsStr
		}
	}

	if format, ok := args["output_format"]; ok && format != nil {
		if formatStr, ok := format.(string); ok {
			outputFormat = formatStr
		}
	}

	output, err := k.executeKubectl("get", "services", "-n", namespace, "-o", outputFormat)
	if err != nil {
		return mcp.NewToolResultError(fmt.Sprintf("获取Service信息失败: %v", err)), nil
	}

	return mcp.NewToolResultText(string(output)), nil
}

// 获取Pod日志
func (k *K8sMCPServer) handleGetPodLogs(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	podName, err := request.RequireString("pod_name")
	if err != nil {
		return mcp.NewToolResultError("pod_name 参数是必需的"), nil
	}

	args := request.GetArguments()
	namespace := k.config.Namespace
	container := ""
	tailLines := ""
	follow := false

	if ns, ok := args["namespace"]; ok && ns != nil {
		if nsStr, ok := ns.(string); ok && nsStr != "" {
			namespace = nsStr
		}
	}

	if cont, ok := args["container"]; ok && cont != nil {
		if contStr, ok := cont.(string); ok && contStr != "" {
			container = contStr
		}
	}

	if tail, ok := args["tail_lines"]; ok && tail != nil {
		if tailStr, ok := tail.(string); ok && tailStr != "" {
			tailLines = tailStr
		}
	}

	if f, ok := args["follow"]; ok && f != nil {
		if fBool, ok := f.(bool); ok {
			follow = fBool
		}
	}

	kubectlArgs := []string{"logs", podName, "-n", namespace}

	if container != "" {
		kubectlArgs = append(kubectlArgs, "-c", container)
	}

	if tailLines != "" {
		kubectlArgs = append(kubectlArgs, "--tail", tailLines)
	}

	if follow {
		kubectlArgs = append(kubectlArgs, "-f")
	}

	output, err := k.executeKubectl(kubectlArgs...)
	if err != nil {
		return mcp.NewToolResultError(fmt.Sprintf("获取Pod日志失败: %v", err)), nil
	}

	return mcp.NewToolResultText(string(output)), nil
}

// 描述资源
func (k *K8sMCPServer) handleDescribeResource(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	resourceType, err := request.RequireString("resource_type")
	if err != nil {
		return mcp.NewToolResultError("resource_type 参数是必需的"), nil
	}

	resourceName, err := request.RequireString("resource_name")
	if err != nil {
		return mcp.NewToolResultError("resource_name 参数是必需的"), nil
	}

	args := request.GetArguments()
	namespace := k.config.Namespace

	if ns, ok := args["namespace"]; ok && ns != nil {
		if nsStr, ok := ns.(string); ok && nsStr != "" {
			namespace = nsStr
		}
	}

	kubectlArgs := []string{"describe", resourceType, resourceName}
	if namespace != "" {
		kubectlArgs = append(kubectlArgs, "-n", namespace)
	}

	output, err := k.executeKubectl(kubectlArgs...)
	if err != nil {
		return mcp.NewToolResultError(fmt.Sprintf("描述资源失败: %v", err)), nil
	}

	return mcp.NewToolResultText(string(output)), nil
}

// 扩缩容Deployment
func (k *K8sMCPServer) handleScaleDeployment(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	deploymentName, err := request.RequireString("deployment_name")
	if err != nil {
		return mcp.NewToolResultError("deployment_name 参数是必需的"), nil
	}

	args := request.GetArguments()
	replicas := ""
	namespace := k.config.Namespace

	if rep, ok := args["replicas"]; ok && rep != nil {
		if repStr, ok := rep.(string); ok {
			replicas = repStr
		} else if repNum, ok := rep.(float64); ok {
			replicas = fmt.Sprintf("%.0f", repNum)
		}
	}

	if replicas == "" {
		return mcp.NewToolResultError("replicas 参数是必需的"), nil
	}

	if ns, ok := args["namespace"]; ok && ns != nil {
		if nsStr, ok := ns.(string); ok && nsStr != "" {
			namespace = nsStr
		}
	}

	output, err := k.executeKubectl("scale", "deployment", deploymentName, "--replicas", replicas, "-n", namespace)
	if err != nil {
		return mcp.NewToolResultError(fmt.Sprintf("扩缩容Deployment失败: %v", err)), nil
	}

	return mcp.NewToolResultText(string(output)), nil
}

// 执行kubectl命令
func (k *K8sMCPServer) handleExecuteKubectl(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	command, err := request.RequireString("command")
	if err != nil {
		return mcp.NewToolResultError("command 参数是必需的"), nil
	}

	// 解析命令参数
	cmdArgs := strings.Fields(command)
	if len(cmdArgs) == 0 {
		return mcp.NewToolResultError("command 不能为空"), nil
	}

	output, err := k.executeKubectl(cmdArgs...)
	if err != nil {
		return mcp.NewToolResultError(fmt.Sprintf("执行kubectl命令失败: %v", err)), nil
	}

	return mcp.NewToolResultText(string(output)), nil
}

// 应用YAML配置
func (k *K8sMCPServer) handleApplyYAML(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	yamlContent, err := request.RequireString("yaml_content")
	if err != nil {
		return mcp.NewToolResultError("yaml_content 参数是必需的"), nil
	}

	args := request.GetArguments()
	namespace := k.config.Namespace

	if ns, ok := args["namespace"]; ok && ns != nil {
		if nsStr, ok := ns.(string); ok && nsStr != "" {
			namespace = nsStr
		}
	}

	// 创建临时文件
	tmpFile := "/tmp/k8s-mcp-apply.yaml"
	if err := writeToFile(tmpFile, yamlContent); err != nil {
		return mcp.NewToolResultError(fmt.Sprintf("创建临时文件失败: %v", err)), nil
	}

	kubectlArgs := []string{"apply", "-f", tmpFile}
	if namespace != "" {
		kubectlArgs = append(kubectlArgs, "-n", namespace)
	}

	output, err := k.executeKubectl(kubectlArgs...)
	if err != nil {
		return mcp.NewToolResultError(fmt.Sprintf("应用YAML配置失败: %v", err)), nil
	}

	// 清理临时文件
	removeFile(tmpFile)

	return mcp.NewToolResultText(string(output)), nil
}

// 删除资源
func (k *K8sMCPServer) handleDeleteResource(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	resourceType, err := request.RequireString("resource_type")
	if err != nil {
		return mcp.NewToolResultError("resource_type 参数是必需的"), nil
	}

	resourceName, err := request.RequireString("resource_name")
	if err != nil {
		return mcp.NewToolResultError("resource_name 参数是必需的"), nil
	}

	args := request.GetArguments()
	namespace := k.config.Namespace

	if ns, ok := args["namespace"]; ok && ns != nil {
		if nsStr, ok := ns.(string); ok && nsStr != "" {
			namespace = nsStr
		}
	}

	kubectlArgs := []string{"delete", resourceType, resourceName}
	if namespace != "" {
		kubectlArgs = append(kubectlArgs, "-n", namespace)
	}

	output, err := k.executeKubectl(kubectlArgs...)
	if err != nil {
		return mcp.NewToolResultError(fmt.Sprintf("删除资源失败: %v", err)), nil
	}

	return mcp.NewToolResultText(string(output)), nil
}

// 获取命名空间
func (k *K8sMCPServer) handleGetNamespaces(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	output, err := k.executeKubectl("get", "namespaces")
	if err != nil {
		return mcp.NewToolResultError(fmt.Sprintf("获取命名空间失败: %v", err)), nil
	}

	return mcp.NewToolResultText(string(output)), nil
}
